#include "stdafx.h"
#include "GlobalSkinData.h"


#include "UIUtil.h"
#include "TimerUtil.h"

CGlobalSkinData::CGlobalSkinData()
{
    m_pCapture = NULL;
    m_pPopup = NULL;
    m_nReleaseTimerId = 0;
    m_uFilterDragdropMsgCount = 0;
}

CGlobalSkinData::~CGlobalSkinData()
{
    DestroyReleaseQueue();
}

void CGlobalSkinData::SetCapture(IXFrame* pCapture)
{
    XWND xPrevWnd = NULL;

    IXFrame* pOldCapture = m_pCapture;

    if(m_pCapture != NULL)
    {
        m_pCapture->OnCaptureLost();
    }

    if(m_pCapture != NULL && m_pCapture->RefCount() > 0)
        m_pCapture->Release();

    m_pCapture = pCapture;

    if(m_pCapture != NULL)
        m_pCapture->AddRef();

    if(m_pCapture != NULL)
    {
        XWND xCurWnd = UIUtil::GetHolderWindow(m_pCapture);
        if(xCurWnd != NULL)
		{
			::SetCapture((HWND)xCurWnd);
		}
    }
    else
    {
        if(pOldCapture != NULL)
        {
            ::SetCapture(NULL);
        }
    }
}

IXFrame* CGlobalSkinData::GetCapture()
{
    return m_pCapture;
}

void CGlobalSkinData::SetTrackPopupMenu(IXMenuPre* pPopup)
{
    XASSERT_ERROR(pPopup == NULL || m_pPopup == NULL, _T("PopupMenuPre is not NULL"));
    m_pPopup = pPopup;
}

IXMenuPre* CGlobalSkinData::GetTrackPopupMenu()
{
    return m_pPopup;
}


void CGlobalSkinData::QueryControlToRelease(IXControl* pControl)
{
    XASSERT_ERROR(pControl != NULL, _T("CGlobalSkinData::QueryControlToRelease"));
    if(pControl == NULL)
        return;

    if(dynamic_cast<IXControl*>(m_pCapture) == pControl)
    {
        SetCapture(NULL);
    }

    pControl->ModifyControlFlags(ESkin_Valid, FALSE);
    m_ReleaseQueue.insert(pControl);
    if(m_nReleaseTimerId == 0)
    {
        m_nReleaseTimerId = TimerUtil::SetTimer(this, 200, NULL);
    }
}

void CGlobalSkinData::FilterDragdropMsg(BOOL bEnable)
{
    if(bEnable)
    {
        ++ m_uFilterDragdropMsgCount;
        if(m_uFilterDragdropMsgCount == 1)
        {
            UIUtil::FilterWindowMessage(0x0049 /*WM_COPYGLOBALDATA*/, 1);
            UIUtil::FilterWindowMessage(WM_DROPFILES, 1);
        }
    }
    else
    {
        -- m_uFilterDragdropMsgCount;
        if(m_uFilterDragdropMsgCount == 0)
        {
            UIUtil::FilterWindowMessage(0x0049 /*WM_COPYGLOBALDATA*/, 2);
            UIUtil::FilterWindowMessage(WM_DROPFILES, 2);
        }
    }

}

//////////////////////////////////////////////////////////////////////////
// IXTimer
void CGlobalSkinData::OnTimer(UINT_PTR uTimerId, void* pData)
{
    if(uTimerId == m_nReleaseTimerId)
    {
        ReleaseQueue::iterator IteCtrl = m_ReleaseQueue.begin();
        while(IteCtrl != m_ReleaseQueue.end())
        {
            IXControl*& pControl = *IteCtrl;
            if(pControl->GetEventNestedCount() <= 0)
            {
                pControl->OnFinalRelease();
                XFree(pControl);
                IteCtrl = m_ReleaseQueue.erase(IteCtrl);
            }
            else
            {
                ++ IteCtrl;
            }
        }
        if(m_ReleaseQueue.size() <= 0)
        {
            TimerUtil::KillTimer(m_nReleaseTimerId);
            m_nReleaseTimerId = 0;
        }
    }
}

//////////////////////////////////////////////////////////////////////////
void CGlobalSkinData::DestroyReleaseQueue()
{
    if(m_nReleaseTimerId != NULL)
    {
        TimerUtil::KillTimer(m_nReleaseTimerId);
        m_nReleaseTimerId = 0;
    }

    ReleaseQueue::iterator IteCtrl = m_ReleaseQueue.begin();
    while(IteCtrl != m_ReleaseQueue.end())
    {
        IXControl*& pControl = *IteCtrl;
        pControl->OnFinalRelease();
        XFree(pControl);
        ++ IteCtrl;
    }
    m_ReleaseQueue.clear();
}
